﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using eWallet.Data.Local;

namespace eWallet.Windows.Controls
{
	/// <summary>
	/// Interaction logic for SecretsList.xaml
	/// </summary>
	public partial class SecretsList : UserControl
	{
		public SecretsList()
		{
			InitializeComponent();

			this.ShowTagCloud = true;
		}

		private EventHandler<ItemActionEventArgs<eWalletDataSet.GroupsRow>> GroupOpeningHandler;
		/// <summary>
		/// Fired when the user selects to open a group.
		/// </summary>
		public event EventHandler<ItemActionEventArgs<eWalletDataSet.GroupsRow>> GroupOpening
		{
			add { this.GroupOpeningHandler += value; }
			remove { this.GroupOpeningHandler -= value; }
		}

		private EventHandler<EventArgs> NewSecretHandler;
		/// <summary>
		/// Fired when the user wants to create a new secret.
		/// </summary>
		public event EventHandler<EventArgs> NewSecret
		{
			add { this.NewSecretHandler += value; }
			remove { this.NewSecretHandler -= value; }
		}

		private EventHandler<ItemActionEventArgs<IEnumerable<eWalletDataSet.SecretsRow>>> SecretsDeletingHandler;
		/// <summary>
		/// Fired when the user selects to delete one or more secrets.
		/// </summary>
		public event EventHandler<ItemActionEventArgs<IEnumerable<eWalletDataSet.SecretsRow>>> SecretsDeleting
		{
			add { this.SecretsDeletingHandler += value; }
			remove { this.SecretsDeletingHandler -= value; }
		}

		private EventHandler<ItemActionEventArgs<eWalletDataSet.SecretsRow>> SecretOpeningHandler;
		/// <summary>
		/// 
		/// </summary>
		public event EventHandler<ItemActionEventArgs<eWalletDataSet.SecretsRow>> SecretOpening
		{
			add { this.SecretOpeningHandler += value; }
			remove { this.SecretOpeningHandler -= value; }
		}

		private eWalletDataSet _DataSource;
		public eWalletDataSet DataSource
		{
			get { return _DataSource; }
			set
			{
				_DataSource = value;
				this.TagCloud.ClearSelection();
				this.TagCloud_SelectedLabelsChanged(this, EventArgs.Empty);
			}
		}

		private bool _ShowTagCloud;
		public bool ShowTagCloud
		{
			get { return _ShowTagCloud; }
			set
			{
				if (this.ShowTagCloud != value)
				{
					_ShowTagCloud = value;

					if (value)
					{
						this.TagsGroup.Visibility = Visibility.Visible;
					}
					else
					{
						this.TagsGroup.Visibility = Visibility.Collapsed;
					}
				}
			}
		}



		protected virtual void OnGroupOpening(ItemActionEventArgs<eWalletDataSet.GroupsRow> e)
		{
			if (null != this.GroupOpeningHandler)
			{
				this.GroupOpeningHandler(this, e);
			}
		}

		protected virtual void OnNewSecret(EventArgs e)
		{
			if (null != this.NewSecretHandler)
			{
				this.NewSecretHandler(this, e);
			}
		}

		protected virtual void OnSecretsDeleting(ItemActionEventArgs<IEnumerable<eWalletDataSet.SecretsRow>> e)
		{
			if (null != this.SecretsDeletingHandler)
			{
				this.SecretsDeletingHandler(this, e);
			}
		}

		protected virtual void OnSecretOpening(ItemActionEventArgs<eWalletDataSet.SecretsRow> e)
		{
			if (null != this.SecretOpeningHandler)
			{
				this.SecretOpeningHandler(this, e);
			}
		}



		private IEnumerable<eWalletDataSet.SecretsRow> GetSelectedSecretRows()
		{
			foreach (var item in this.SecretListView.SelectedItems)
			{
				Guid id = (Guid)item.GetType().InvokeMember("Id", System.Reflection.BindingFlags.GetProperty, null, item, null);
				var row = this.DataSource.Secrets.FirstOrDefault(s => s.Id == id);
				if (null != row)
				{
					yield return row;
				}
			}
		}

		private void OpenSelectedSecret()
		{
			var row = this.GetSelectedSecretRows().FirstOrDefault();
			if (null != row)
			{
				this.OnSecretOpening(new ItemActionEventArgs<eWalletDataSet.SecretsRow>(row));
			}
		}

		private void OpenSelectedSecretGroup()
		{
			var row = this.GetSelectedSecretRows().FirstOrDefault();
			if (null != row && null != row.GroupsRow)
			{
				this.OnGroupOpening(new ItemActionEventArgs<eWalletDataSet.GroupsRow>(row.GroupsRow));
			}
		}

		private void TagCloud_TagClicked(object sender, ItemClickedEventArgs e)
		{
		}

		private void TagCloud_SelectedLabelsChanged(object sender, EventArgs e)
		{
			var tags = this.DataSource.Tags.Select(this.TagCloud.SelectedLabels);
			var secrets = this.DataSource.Secrets.Select(tags);

			Dictionary<string, int> tagList = new Dictionary<string, int>();
			this.SecretListView.Items.Clear();

			foreach (var secret in secrets)
			{
				var item = new { Id = secret.Id, Group = secret.GroupsRow.Name, Description = secret.IsDescriptionNull() ? "" : secret.Description, Tags = string.Join(", ", secret.GetTags().ToArray()), ContentType = secret.ContentType, FileName = secret.IsFileNameNull() ? "" : secret.FileName };
				this.SecretListView.Items.Add(item);

				foreach (string tag in secret.GetTags())
				{
					if (null == tags.FirstOrDefault(t => t.Label == tag))
					{
						if (tagList.ContainsKey(tag))
						{
							tagList[tag]++;
						}
						else
						{
							tagList.Add(tag, 1);
						}
					}
				}
			}

			var list = from t in tagList orderby t.Key select t;
			this.TagCloud.Items.Clear();
			foreach (var item in list)
			{
				this.TagCloud.Items.Add(new Tag(item.Key, item.Value));
			}


		}

		private void SecretListView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
		{
			this.OpenSelectedSecret();
		}

		private void SecretListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			this.OpenMenuItem.IsEnabled = this.SecretListView.SelectedItems.Count == 1;
			this.OpenGroupMenuItem.IsEnabled = this.SecretListView.SelectedItems.Count == 1;
			this.DeleteMenuItem.IsEnabled = this.SecretListView.SelectedItems.Count > 0;
		}

		private void OpenMenuItem_Click(object sender, RoutedEventArgs e)
		{
			this.OpenSelectedSecret();
		}

		private void OpenGroupMenuItem_Click(object sender, RoutedEventArgs e)
		{
			this.OpenSelectedSecretGroup();
		}

		private void DeleteMenuItem_Click(object sender, RoutedEventArgs e)
		{
			this.OnSecretsDeleting(new ItemActionEventArgs<IEnumerable<eWalletDataSet.SecretsRow>>(this.GetSelectedSecretRows()));
		}

		private void NewMenuItem_Click(object sender, RoutedEventArgs e)
		{
			this.OnNewSecret(EventArgs.Empty);
		}

	}
}
